﻿#if NETSTANDARD2_0 
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
#endif

#if NET35
using Kernelx.Common.DependencyInjection;
#endif

using System; 



namespace Kernelx.Contexts.Configuration
{
    using Defaults;
    using Core;
    using Extensions;
    using Kernelx.Contexts.ClientImpls;

    /// <summary>
    /// 
    /// </summary>
    public static class ClientContextsExtensions
    {

        private static Func<IWorkloadContext, WorkloadEnvironment> _getWorkloadEnvironment;
        /// <summary>
        /// 注册<see cref="WorkloadEnvironment"/>的实例 
        /// </summary>
        /// <typeparam name="TEnvironment"></typeparam>
        /// <param name="getWorkloadEnvironment"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        public static WorkloadContextOptions RegisterWorkloadEnvironment<TEnvironment>(this WorkloadContextOptions ctxOpts, Func<IWorkloadContext, TEnvironment> getWorkloadEnvironment)
            where TEnvironment : WorkloadEnvironment, new()
        {
            if (getWorkloadEnvironment == null)
                throw new ArgumentNullException(nameof(getWorkloadEnvironment));

            var envinment = new TEnvironment();

            ctxOpts.Services.AddSingleton(envinment);
            ctxOpts.Services.AddSingleton<WorkloadEnvironment>(envinment);

            _getWorkloadEnvironment =
#if NET35
        p => getWorkloadEnvironment(p);
#endif
#if NETSTANDARD2_0
            getWorkloadEnvironment;
#endif
            return ctxOpts;
        }



        internal static void UseWorkloadStartupContext(this ClientWorkloadContextOptions options, Action<ClientWorkloadContextOptions> action)
        {
            if (action == null)
                throw new ArgumentNullException(nameof(action));
            action(options);
            ClientWorkloadContext.CurrentUser = options.DefaultCurrentUser;
            var ctx = WorkloadStartupContext.Current;
            var env = _getWorkloadEnvironment?.Invoke(ctx);
            env?.CopyTo(ctx.GetService(env.GetType()), true);
        }

    }
}
